function printCoord(pt:{x:number; y:number}) {
    console.log("the coordinate's x value is "+ pt.x);
    console.log("the coordinate's y value is "+ pt.y);
}

printCoord({x: 3, y: 7});

type ID = number | string | {x:number; y:number};

function printId(id:ID) {
    console.log("ID : " + id);
}

printId(1);
printId("xxxxx");



type UserInputSanitizedString = string;
function sanitize(str:string) {
    return "";
}
function sanitizeInput(str:string):UserInputSanitizedString {
    return sanitize(str);
}
function getInput():UserInputSanitizedString {
    return "1234";
}

let userInput = sanitizeInput(getInput());
userInput = "new input";

// Interfaces
interface Point {
    x:number;
    y:number;
}
function printCoord1(pt:Point) {
    console.log("the coordinate's x value is "+ pt.x);
    console.log("the coordinate's y value is "+ pt.y);
}
printCoord1({x:100, y:100})

// Interface
interface Animal {
    name:string;
}

interface Bear extends Animal {
    honey:boolean;
}
function getBear():Bear {
    let bear = {name:"bear", honey:true}
    return bear;
}
const bear = getBear();
bear.name;
bear.honey;

type Animal1 = {
    name: string;
}

type Bear1 = Animal1 & {
    honey: boolean;
}
function getBear1():Bear1 {
    let bear = {name:"bear", honey:true}
    return bear;
}
const bear1 = getBear1();
bear1.name;
bear1.honey;

interface Window {
    title: string;
}

interface Window {
    ts: string;
}

const src = 'const a = "Hello World"';
// 相当于是扩展了
window.ts;
window.title;

// Type就不能重复定义
// type Window =  {
//     title:string;
// }
// type Window {
//     ts: string;
// }
// 这个as会被运行时被去除，这里强制转换不会有异常
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement; 
const myCanvas1 = <HTMLCanvasElement>document.getElementById("main_canvas");

// 不允许
// const x = "hello" as number;
// 有时候这种过于保守，可以使用, 先转为any，再将any转为你想转换的类型
const x = "hello" as any as number;

// 文字类型
// let只能推断类型
let changingString = "Hello world";
changingString = "Olá Mundo"
changingString;
// const是可以推断变量的值
const constantString = "Hello world";
constantString;
// 已经被定义为hello文字类型了
let y: "hello" = "hello";
y = "hello";
// y = "yyyy";
// 可以理解为文字类型中指定的文字值
function printText(s:string, alignment:"left"|"right"|"center") {

}

printText("Hello world", "left");
// 类似java的注解，只允许指定的值
// printText("G'day, mate", "cente");

function compare(a:string, b:string): -1 | 0 | 1 {
    return a === b ? 0: a > b ? 1 : -1;
}

interface Options {
    width: number;
}

function configure(x:Options | "auto") {

}

configure({width: 100});
configure("auto");
// 只能是auto类型
// configure("automatic");


const obj = {couter: 0};
let someCondition = false;
if(someCondition) {
    obj.couter = 1;
}


declare function handleRequest(url:string, method:"GET" | "POST"): void;
// const method = "GET";
// const req = {url: "http://example.com", method:method}
// // 指定的值必须是相等的, 不能经过封装
// handleRequest(req.url, req.method)

// const method = "GET";
// const req = {url: "http://example.com", method:method as "GET"}
// // 指定的值必须是相等的, 或者强制类型转换一下
// handleRequest(req.url, req.method as "GET")

const method = "GET";
const req = {url: "http://example.com", method:method} as const;
// 指定的值必须是相等的, 或者设置不变变量也可以
handleRequest(req.url, req.method);


function doSomething(x:string | null) {
    if(x === null) {
        // do nothing
    } else {
        console.log("Hello, " + x.toLocaleUpperCase());
    }
}
function liveDangerously(x?:number | null) {
    console.log(x!.toFixed())
}

const oneHundred:bigint = BigInt(100);

const anotherHundred = 100n;
// 唯一变量
const firstName = Symbol("name");
const secondName = Symbol("name");

// if(firstName === secondName) {

// }
